package com.jocund.quicktest;

import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MessagingManager {
	private HashMap<Integer, Conversation> conversationMap;
	private BlockingQueue<Message> messageQueue;
	
	private MessageDispatcher dispatcher;
	private Thread dispatcherWroker;
	
	private Log log = LogFactory.getLog(MessagingManager.class);
	
	public MessagingManager(){
		this.conversationMap = new HashMap<Integer, Conversation>();
		this.messageQueue = new ArrayBlockingQueue<Message>(1000);
		this.dispatcher = new MessageDispatcher(messageQueue, conversationMap);
		this.dispatcherWroker = new Thread(dispatcher,"MessageDispatcher");
	}
	
	public void initialize(){
		this.dispatcherWroker.start();
	}
	
	public void pushMessage(Message msg, int conversationId){
		try {
			log.debug(String.format("Message is pushed to conversation %d...", conversationId));
			this.messageQueue.put(msg);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			log.error(e.toString());
		}
	}
	
	public Message recvMessage(String userUniqueName, int conversationId){
		Conversation conv = this.conversationMap.get(conversationId);
		Message msg = null;
		try {
			msg = conv.recvMessage(userUniqueName);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UserExpiredException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return msg;
	}
	
	public void keepAlive(String userUniqueName, int conversationId){
		Conversation conv = this.conversationMap.get(conversationId);
		try {
			conv.reportUserAlive(userUniqueName);
		} catch (NotExistException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public int createConversation(User[] users){
		Conversation conv = new Conversation();
		this.conversationMap.put(conv.getConversationId(), conv);
		for (User user : users){
			try {
				conv.addUser(user);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		int conversationId = conv.getConversationId();
		return conversationId;
	}
}
